﻿using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.SceneManagement;

#if UNITY_EDITOR
using UnityEditor;
public partial class AutoGenerator
    : MonoBehaviour
{
    [CustomEditor(typeof(AutoGenerator))]
    private class AutoGeneratorEditor
        : Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            AutoGenerator generator = target as AutoGenerator;
            if (generator == null)
                return;

            if (generator.size.x * generator.size.y > 0 && generator.template != null && GUILayout.Button("Generate"))
            {
                generator.Generate();
            }
            if(GUILayout.Button("Clear"))
            {
                generator.Clear();
            }
        }
    }
}
#endif

public partial class AutoGenerator : MonoBehaviour
{
    public Vector2Int size;

    public MeshRenderer template;

    private MaterialPropertyBlock mpb;

    public GameObject autoLoader;

    public GameObject[] autoHide;

    public GameObject dynamicRoot;
    public GameObject staticRoot;

    public Transform moveRoot;
    public Mesh combinedMesh;

    [ContextMenu("手动绑定")]
    public void ManualStaticCombie()
    {
        MeshFilter mf = template.GetComponent<MeshFilter>();
        if(mf != null)
        {
            Debug.Log(mf.sharedMesh.isReadable);
        }
        Debug.Log("开始手动绑定");
        Profiler.BeginSample("StaticCombie");
        StaticBatchingUtility.Combine(this.gameObject);
        Profiler.EndSample();
    }

    private GameObject loaded1 = null;
    private GameObject loaded2 = null;

    public MeshFilter dynamicMesh;
    public MeshFilter staticMesh;

    private void OnGUI()
    {
        return;
        //if(autoLoader != null && loaded1 == null)
        //{
        //    if (GUI.Button(new Rect(0, 0, 200, 200), "LoadLess"))
        //    {
        //        loaded1 = Instantiate(autoLoader);
        //        loaded1.transform.SetParent(this.transform);
        //        loaded1.transform.localPosition = new Vector3(-10, 2, 3);

        //        StaticBatchingUtility.Combine(loaded1);
        //        //MeshFilter mf = loaded1.GetComponentInChildren<MeshFilter>();
        //        //if (mf != null)
        //        //{
        //        //    mf.gameObject.SetActive(false);
        //        //}
        //    }
        //}
        //if (autoLoader != null && loaded2 == null)
        //{
        //    if (GUI.Button(new Rect(200, 0, 200, 200), "Load"))
        //    {
        //        loaded2 = Instantiate(autoLoader);
        //        loaded2.transform.SetParent(this.transform);
        //        loaded2.transform.localPosition = new Vector3(0, 2, 3);
        //        MeshFilter mf = loaded2.GetComponentInChildren<MeshFilter>();
        //        StaticBatchingUtility.Combine(loaded2);
        //    }
        //}
        if(autoHide != null && autoHide.Length > 0 && autoHide[0] != null)
        {
            if (GUI.Button(new Rect(50, 0, 50, 50), autoHide[0].gameObject.activeSelf ? "Hide" : "Show"))
            {
                bool show = autoHide[0].activeSelf;
                foreach (var item in autoHide)
                {
                    item.gameObject.SetActive(!show);
                }
            }
        }
        if (GUI.Button(new Rect(0, 0, 50, 50), "Swap"))
        {
            dynamicRoot.gameObject.SetActive(staticRoot.activeSelf);
            staticRoot.gameObject.SetActive(!dynamicRoot.activeSelf);
        }
        if (GUI.Button(new Rect(100, 0, 50, 50), "Camera"))
        {
            if(Camera.main.transform.position.y < -4.9f)
            {
                Camera.main.transform.position = new Vector3(0, 0, 6);
            }
            else
            {
                Camera.main.transform.position = new Vector3(0, -5f, 6);
            }
        }
        if (!converted && GUI.Button(new Rect(150, 0, 50, 50), "Convert"))
        {
            StaticBatchingUtility.Combine(dynamicRoot);
            combinedMesh = dynamicRoot.GetComponentInChildren<MeshFilter>().sharedMesh;
            Debug.LogError(dynamicMesh.sharedMesh.GetInstanceID());
            Debug.LogError(staticMesh.sharedMesh.GetInstanceID());
            converted = true;
        }

        if (GUI.Button(new Rect(200, 0, 50, 50), "Foreach"))
        {
            //遍历所有网格渲染器
            var allMeshRenderers = FindObjectsOfType<MeshRenderer>();
            foreach (var item in allMeshRenderers)
            {
                //第一次获取material属性会为其创建新的材质球实例
                //因此会打断合批
                var id = item.material.GetInstanceID();
            }
        }
        if (GUI.Button(new Rect(250, 0, 50, 50), "Recycle"))
        {
            if(combinedMesh != null)
            {
                Destroy(combinedMesh);
                //Resources.UnloadAsset(combinedMesh);
                Resources.UnloadUnusedAssets();
            }
            //切换场景
            //SceneManager.LoadScene(1, LoadSceneMode.Additive);
        }
    }
    bool converted = false;
    private void Generate()
    {
        mpb = new MaterialPropertyBlock();

        for (int row = 0; row < size.x; row++)
        {
            for (int column = 0; column < size.y; column++)
            {
                Vector3 pos = new Vector3(column * 1.2f, row * 1.2f, 0f);
                MeshRenderer newInstnace = Instantiate(template);
                newInstnace.transform.SetParent(this.transform);
                newInstnace.transform.localPosition = pos;
                //newInstnace.transform.localScale = new Vector3(
                //    UnityEngine.Random.Range(0f, 1f),
                //    UnityEngine.Random.Range(0f, 1f),
                //    UnityEngine.Random.Range(0f, 1f));
                newInstnace.transform.localScale = Vector3.one;

                //var color = new Color(row * 1f / size.x , column * 1f / size.y, 0f);

                ////Wrong
                ////newInstnace.material.SetColor("_Color", color);

                ////Right
                //newInstnace.GetPropertyBlock(mpb);
                //mpb.SetColor("_Color", color);
                //newInstnace.SetPropertyBlock(mpb);
            }
        }
    }

    /// <summary>
    /// 清空所有
    /// </summary>
    private void Clear()
    {
        for (int i = transform.childCount - 1; i >= 0; i--)
        {
            DestroyImmediate(transform.GetChild(i).gameObject);
        }
    }

    public void Update()
    {
        if (moveRoot == null)
            return;

        Vector3 offset = Vector3.zero;
        if(Input.GetKeyDown(KeyCode.UpArrow))
        {
            offset.y = 0.1f;
        }
        moveRoot.localPosition += offset;
    }
}
